package com.dana1.nos.core;


import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Calendar;
import java.util.Collections;
import java.util.TimeZone;
import java.util.UUID;

import junit.framework.Assert;

import org.apache.commons.codec.binary.Hex;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.dana1.nos.old.generator.TimeBasedUUIDGenerator;

public class TestTimeBasedUUIDGenerator
{
	TimeBasedUUIDGenerator generator;
	private long EPOCH_OFFSET_MILLIS;

	@Before
	public void setUp() throws Exception
	{
		generator = new TimeBasedUUIDGenerator();
		Calendar c1 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
		c1.setTimeInMillis(0l);
		c1.set(Calendar.YEAR, 1582);
		c1.set(Calendar.MONTH, Calendar.OCTOBER);
		c1.set(Calendar.DAY_OF_MONTH, 15);
		EPOCH_OFFSET_MILLIS = -c1.getTimeInMillis();
	}
	@Test
	public void validateTimeStampIsUTCandValid()
	{
		long currentTimeBefore = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTimeInMillis();
		UUID uuids = (UUID)generator.nextValue(null); 
		long currentTimeAfter = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTimeInMillis();
		long mappedTime = uuids.timestamp()/10000-EPOCH_OFFSET_MILLIS;
		Assert.assertTrue("UUID has invalid timestamp was "+mappedTime+" expected "+currentTimeBefore,mappedTime>= currentTimeBefore);
		Assert.assertTrue("UUID has invalid timestamp was "+mappedTime+" expected "+currentTimeAfter,mappedTime<= currentTimeAfter);
	}
	@Test
	public void validateTimeStampDoesntRollBackwards()
	{
		UUID [] uuids = new UUID[10001]; 
		for (int i = uuids.length-1; i >=0; i--)
			uuids[i] = (UUID)generator.nextValue(null);
		UUID last = uuids[uuids.length-1];
		for (int i = uuids.length-2; i >=0; last=uuids[i--])
			Assert.assertTrue("Timestamp is going backwards",uuids[i].timestamp()>last.timestamp());
	}
	@Test
	public void validateVariant()
	{
		UUID uuid = (UUID)generator.nextValue(null);
		Assert.assertEquals("Variant must be 2",2, uuid.variant());
	}
	@Test
	public void validateVersion()
	{
		UUID uuid = (UUID)generator.nextValue(null);
		Assert.assertEquals("Version must be 1",1, uuid.version());
	}
	@Test
	public void validateNode() throws SocketException
	{
		UUID uuid = (UUID)generator.nextValue(null);
		for (NetworkInterface nic : Collections.list(NetworkInterface.getNetworkInterfaces()))
			if (!nic.isLoopback())
			{
				long encoded = Long.parseLong(new String(Hex.encodeHex(nic.getHardwareAddress(),true)),16);
				if (encoded == uuid.node()) 
				{
					System.out.println("Discovered NIC "+Long.toHexString(uuid.node()));
					return;
				}
			}
		Assert.fail("Unable to find a matching HW address for " + Long.toHexString(uuid.node()));
	}
	@After
	public void tearDown() throws Exception
	{
	}

}
